﻿/*----------------------------------------------------------------
//  <copyright file="EntityBase.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2024-03-06 09:54</last-date>
//----------------------------------------------------------------*/

using Newtonsoft.Json;

namespace MicroCloud.Entity
{
    #region "实体类基类"
    /// <summary>
    /// 实体类基类
    /// </summary>
    /// <typeparam name="TKey">实体主键类型</typeparam>
    //[MemoryOptimized]
    [ValueGenerate(ValueGenerateRule.Never, ValueGenerateMode.Snowflake)]
    public abstract class EntityBase<TKey> : IEntity<TKey>
        where TKey : IEquatable<TKey>
    {
        #region "属性"
        #region "获取或设置 编号"
        /// <summary>
        /// 获取或设置 编号
        /// <para>主键，唯一标识。</para>
        /// </summary>
        [Key, Column("Id")]
        [Required(AllowEmptyStrings = false)]
        [StringSize(StringSizeType.Code)]
        [DisplayName("编号")]
        public virtual TKey Id { get; set; }
        #endregion

        //非实体映射属性
        #region "获取 实体类型"
        /// <summary>
        /// 获取 实体类型
        /// </summary>
        [NotMapped]
        [DisplayName("实体类型")]
        [JsonIgnore]
        public virtual string EntityType => GetType().GetFullNameWithModule();
        #endregion

        #endregion

        #region "方法"
        #region "判断两个实体是否是同一数据记录的实体"
        /// <summary>
        /// 判断两个实体是否是同一数据记录的实体
        /// </summary>
        /// <param name="obj">要比较的实体信息</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return false;
            }
            if (obj is not EntityBase<TKey> entity)
            {
                return false;
            }
            return IsKeyEqual(entity.Id, Id);
        }
        #endregion
        #region "实体ID是否相等"
        /// <summary>
        /// 实体ID是否相等
        /// </summary>
        /// <param name="id1"></param>
        /// <param name="id2"></param>
        /// <returns></returns>
        public static bool IsKeyEqual(TKey id1, TKey id2)
        {
            if (id1 == null && id2 == null)
            {
                return true;
            }
            if (id1 == null || id2 == null)
            {
                return false;
            }

            Type type = typeof(TKey);
            if (type.IsDeriveClassFrom(typeof(IEquatable<TKey>)))
            {
                return id1.Equals(id2);
            }
            return Equals(id1, id2);
        }
        #endregion
        #region "用作特定类型的哈希函数"
        /// <summary>
        /// 用作特定类型的哈希函数
        /// </summary>
        /// <returns>
        /// 当前 <see cref="T:System.Object"/> 的哈希代码，<br/>
        /// 如果<c>Id</c>为<c>null</c>则返回0，
        /// 如果不为<c>null</c>则返回<c>Id</c>对应的哈希值
        /// </returns>
        public override int GetHashCode()
        {
            if (Id == null)
            {
                return 0;
            }
            return Id.ToString().GetHashCode();
        }
        #endregion

        #endregion

    }
    #endregion

}
